package tc.de.krawallmann.gravoblocks.game;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.Sound;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.state.transition.FadeInTransition;
import org.newdawn.slick.state.transition.FadeOutTransition;

import tc.de.krawallmann.extension.HighscoresExtension;
import tc.de.krawallmann.extension.SettingsExtension;
import tc.de.krawallmann.gravoblocks.resource.Language;
import tc.de.krawallmann.gravoblocks.score.Score;
import tc.de.krawallmann.slick.game.AbstractExtendableGame;
import tc.de.krawallmann.slick.game.AbstractMMenuState;
import tc.de.krawallmann.twl.RootPane;
import de.matthiasmann.twl.Button;
import de.matthiasmann.twl.Label;
import de.matthiasmann.twl.ScrollPane;
import de.matthiasmann.twl.ScrollPane.Fixed;
import de.matthiasmann.twl.Table;
import de.matthiasmann.twl.model.SimpleTableModel;

/**
 * The Class ScoresState displays all the scores that have been achieved.
 * 
 * @author KrawallMann
 * @version 1.0
 */
public class ScoresState extends AbstractMMenuState {
	/** The backButton button. */
	private transient Button backButton;

	/** The click. */
	private transient Sound click;
	private transient Label puzzleScoresLabel;

	private transient ScrollPane puzzleScrollPane;

	private transient Table puzzletable;

	/** The "scores" label. */
	private transient Label scoresLabel;

	/** The scroll pane. */
	private transient ScrollPane scrollPane;

	/** The table. */
	private transient Table table;

	/**
	 * Instantiates a new ScoresState.
	 * 
	 * @param menuID
	 *            the menu's id
	 * @param game
	 *            the game
	 */
	public ScoresState(final int menuID, final AbstractExtendableGame game) {
		super(menuID, game);
	}

	/*
	 * (non-Javadoc)
	 * @see tc.de.krawallmann.slick.game.AbstractMMenuState#init(org.newdawn.
	 * slick.GameContainer, org.newdawn.slick.state.StateBasedGame)
	 */
	@Override
	public void init(final GameContainer container, final StateBasedGame game)
			throws SlickException {
		super.init(container, game);
		click = new Sound("tc/de/krawallmann/gravoblocks/resource/click.wav"); //$NON-NLS-1$
		setBackground(new Image("tc/de/krawallmann/gravoblocks/resource/mainmenu.jpg")); //$NON-NLS-1$
	}

	/*
	 * (non-Javadoc)
	 * @see tc.de.krawallmann.twlslick.BasicTWLGameState#layoutRootPane()
	 */
	@Override
	public void layoutRootPane() {
		super.layoutRootPane();

		// Adjust the sizes
		table.adjustSize();
		backButton.adjustSize();
		scoresLabel.adjustSize();
		puzzleScoresLabel.adjustSize();
		scrollPane.setSize(730, 170);
		puzzleScrollPane.setSize(730, 150);

		// Set the positions
		table.setSize(700, Math.max(table.getHeight(), 350));
		scrollPane.setPosition(50, 100);
		backButton.setPosition(750 - backButton.getWidth(), 500);
		scoresLabel.setPosition((getContainer().getWidth() - scoresLabel.getWidth()) / 2, 20);

		puzzleScoresLabel.setPosition(
				(getContainer().getWidth() - puzzleScoresLabel.getWidth()) / 2, 260);
		puzzletable.setSize(700, Math.max(table.getHeight(), 350));
		puzzleScrollPane.setPosition(50, 340);
	}

	/*
	 * (non-Javadoc)
	 * @see tc.de.krawallmann.twl.BasicTWLGameState#reload()
	 */
	@Override
	public void reload() {
		setRootPane(createRootPane());
		layoutRootPane();
	}

	/*
	 * (non-Javadoc)
	 * @see tc.de.krawallmann.twlslick.BasicTWLGameState#createRootPane()
	 */
	@Override
	protected RootPane createRootPane() {
		final RootPane pane = super.createRootPane();

		// Set root theme
		pane.setTheme(""); //$NON-NLS-1$

		// Create the widgets
		scoresLabel = new Label(Language.getString("ScoresState.2")); //$NON-NLS-1$
		scoresLabel.setTheme("label60"); //$NON-NLS-1$

		// Create the widgets
		puzzleScoresLabel = new Label(Language.getString("ScoresState.0")); //$NON-NLS-1$
		puzzleScoresLabel.setTheme("label60"); //$NON-NLS-1$
		puzzletable =
				new Table(
						new SimpleTableModel(
								new String[] {
										Language.getString("ScoresState.1"), Language.getString("ScoresState.3"), Language.getString("ScoresState.6")})); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		puzzletable.setTheme("/table"); //$NON-NLS-1$

		puzzleScrollPane = new ScrollPane(puzzletable);
		puzzleScrollPane.setFixed(Fixed.HORIZONTAL);

		backButton = new Button(Language.getString("ScoresState.4")); //$NON-NLS-1$
		backButton.setTheme("button40"); //$NON-NLS-1$

		table =
				new Table(
						new SimpleTableModel(
								new String[] {
										Language.getString("ScoresState.1"), Language.getString("ScoresState.3"), Language.getString("ScoresState.6"), Language.getString("ScoresState.7")})); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		table.setTheme("/table"); //$NON-NLS-1$

		scrollPane = new ScrollPane(table);
		scrollPane.setFixed(Fixed.HORIZONTAL);

		backButton = new Button(Language.getString("ScoresState.4")); //$NON-NLS-1$
		backButton.setTheme("button40"); //$NON-NLS-1$

		// Add callbacks
		backButton.addCallback(new Runnable() {
			@Override
			public void run() {
				if (SettingsExtension.getSetting(GravoBlocksGame.USE_SOUND)) {
					click.play();
				}
				getGame().enterState(GravoBlocksGame.MAINMENUSTATE, new FadeOutTransition(),
						new FadeInTransition());
			}
		});

		for (final Score s : getGame().getExtension(HighscoresExtension.class).values()) {
			if (Score.PUZZLE.equals(s.getGamemode())) {
				((SimpleTableModel) puzzletable.getModel()).addRow(
						s.isCheat() ? "[CHEAT]" : s.getName(), //$NON-NLS-1$
						s.getPoints(), s.getLines(), s.getLevel());
			} else {
				((SimpleTableModel) table.getModel()).addRow(s.isCheat() ? "[CHEAT]" : s.getName(), //$NON-NLS-1$
						s.getPoints(), s.getLines(), s.getLevel());
			}
		}

		// Add the widgets
		pane.add(scoresLabel);
		pane.add(scrollPane);

		pane.add(puzzleScoresLabel);
		pane.add(puzzleScrollPane);
		pane.add(backButton);

		// Make the widgets focusable
		makeFocusable(backButton);

		return pane;
	}
}
